// ==UserScript==
// @name           Travian Troops Summery
// @Author         vimperator
// @version        1.0
// @namespace      QP
// @description    Travian QP Targets modified
// @include        http://s*.travian*.*/build.php*
// ==/UserScript==

// event listener starts things off once the page is done loading
window.addEventListener("load", function () {
	var DEF_CATATARGET_RANDOM = 99;
	var DEF_CATATARGET_NONE = 0;

	var DEF_ATTACKTYPE_REINFORCE = 2;
	var DEF_ATTACKTYPE_ATTACK = 3;
	var DEF_ATTACKTYPE_RAID = 4;

	var DEF_SCOUTTYPE_RESOURCES = 1;
	var DEF_SCOUTTYPE_DEFENSES = 2;

	var DEF_UNDERSCORE = "_";
	// Keys that depend on villageId or some other info have the underscore, others use the one from the prefix
	var DEF_PARTIALPERMANENTMKEY_INSTANTTROOPMOVE = DEF_UNDERSCORE + "instantTroopsMove";
	var DEF_PARTIALPERMANENTMKEY_VILLAGEREPORTINFO = DEF_UNDERSCORE + "villageReportInfo";
	var DEF_PARTIALPERMANENTMKEY_REPORTSACTION = "reportsAction";
	var DEF_PARTIALPERMANENTMKEY_SINGLEVILLAGEINFO = "singleVillageInfo";
	var DEF_PARTIALPERMANENTMKEY_MERCHANTSTITLE_ARRIVING = "arrivingMerchants";
	var DEF_PARTIALPERMANENTMKEY_MERCHANTSTITLE_OWNMERCHANTS = "ownMerchants";
	var DEF_PARTIALPERMANENTMKEY_LANG_REINFORCEMENTS = "lang_reinforcements";
	var DEF_PARTIALPERMANENTMKEY_PREFIX = getServerName() + DEF_UNDERSCORE + getUserId() + DEF_UNDERSCORE;

	var DEF_ACTION_DELETE_TRADE = "deleteTrade";

	var DEF_UTM_ATTACKTYPEINDEX = 11;
	var DEF_UTM_SCOUTTYPEINDEX = 12;
	var DEF_UTM_CATATARGET1INDEX = 13;
	var DEF_UTM_CATATARGET2INDEX = 14;

	var TRIBE_ROMAN = 0;
	var TRIBE_GAUL = 1;
	var TRIBE_TEUTON = 2;
	var TRIBE_NATURE = 3;
	var TRIBE_NATAR = 4;
	var TRIBE_UNDISCLOSED = 5;


	debug("[-] MAIN ");
	function main() {
		if (isPageRallyPoint(document.location.href)) {
			debug("[-][isPageRallyPoint]");
			getInfoRallyPoint_ReinforcementsLang();
			//getInfoRallyPoint_CreateIncomingAttacksReport();
			transformPageRallyPoint_addOwnTownTotalTroopsTable();
			//transformPageRallyPoint_addLinksForTroopGroups();
			//transformPageRallyPoint_addCoordsForOwnVillageReinfsAway();
		}
	}
	
	function isPageRallyPoint(url) {
		if (getParamFromUrl(url, "id") == 39) { return true; }
		if (getParamFromUrl(url, "gid") == 16) { return true; }
		// check for the 3 links of the rally point (Overview | Send troops | Combat-Simulator)
		var rallyPointLinks = xpathEvaluate('//div[@id="lmid2"]/p[@class="txt_menue"]/a');
		if (rallyPointLinks.snapshotLength > 0) {
			if (rallyPointLinks.snapshotItem(0).href.indexOf("/build.php?id=39") < 0) { return false; }
			if (rallyPointLinks.snapshotItem(1).href.indexOf("/a2b.php") < 0) { return false; }
			if (rallyPointLinks.snapshotItem(2).href.indexOf("/warsim.php") < 0) { return false; }
			// all 3 links above were found
			return true;
		}
		return false;
	}
	
	function getInfoRallyPoint_ReinforcementsLang() {
		debug("[getInfoRallyPoint_ReinforcementsLang] ");
		var activeVillageCoordZ = getActiveVillageCoordZ();

		debug("[getInfoRallyPoint_ReinforcementsLang] activeVillageCoordZ " + activeVillageCoordZ);

		// selects tables of reinforcements (consuming crop), that are of troops from this town (so own troops away)
		var ownReinfsAwayTables = xpathEvaluate('//div[@id="lmid2"]/table/tbody/tr/td/table/tbody/tr/td/img[@class = "res"]/../../../../../../../../tbody/tr/td/a[contains(@href, ' + activeVillageCoordZ + ')]/../../td[2]/a/span[@class = "c0"]');
		if (ownReinfsAwayTables.snapshotLength > 0) {
			var txt = ownReinfsAwayTables.snapshotItem(0).innerHTML;
			txt = txt.split(" ")[0];
			savePermanentLang_Reinforcements(txt);
		}
	}	
	
	/**
	* transformPageRallyPoint_addOwnTownTotalTroopsTable
	* Simplifies rally point page by adding a table with the total troops own'ed by this town, no matter
	* where they are currently. This avoids checking multiple locations to see own many troops this town has.
	* Troops that go or are already in an oasis owned by the current town, cannot be counted on the oasis because
	* they already at the "on the way" or the "in other villages" groups.
	*/
	function transformPageRallyPoint_addOwnTownTotalTroopsTable() {
		debug("[transformPageRallyPoint_addOwnTownTotalTroopsTable] ");
		var activeVillageCoordZ = getActiveVillageCoordZ();

		debug("[transformPageRallyPoint_addOwnTownTotalTroopsTable] activeVillageCoordZ " + activeVillageCoordZ);

		// selects tables with troops from current town OR the oasis titles
		var ownTroopsTables = xpathEvaluate('//div[@id="lmid2"]/table/tbody/tr/td/a[contains(@href, ' + activeVillageCoordZ + ')]/../../../..|//div[@id="lmid2"]/p[@class="b f16"]');

		debug("[transformPageRallyPoint_addOwnTownTotalTroopsTable] ownTroopsTables.snapshotLength " + ownTroopsTables.snapshotLength);
		if (ownTroopsTables.snapshotLength > 0) {
			var totalTable = ownTroopsTables.snapshotItem(0).cloneNode(true);
			var totalTroopsCells = xpathEvaluateInContext(totalTable, 'tbody/tr[3]').snapshotItem(0);

			debug("[transformPageRallyPoint_addOwnTownTotalTroopsTable] BEfor");
			for(var i=1; i<ownTroopsTables.snapshotLength; i++) {	// table 0 is the cloned one above
				var currentTable = ownTroopsTables.snapshotItem(i);
				
				// doesn't count on oasis to not double count
				if (currentTable.nodeName == "P") { break; }

				var currentTroopsCells = xpathEvaluateInContext(currentTable, 'tbody/tr[3]').snapshotItem(0);
				debug("[transformPageRallyPoint_addOwnTownTotalTroopsTable] i "+i+" currentTroopsCells.snapshotLength " + currentTroopsCells.snapshotLength);

				// creates the hero column in case it wasn't in the "totals" table but the hero belongs to this town now
				if (currentTroopsCells.cells.length == 12) {
					// clone the hero icon cell
					var totalTroopsIconsRow = xpathEvaluateInContext(totalTable, 'tbody/tr[2]').snapshotItem(0);
					var currentTroopsHeroIconCell = xpathEvaluateInContext(currentTable, 'tbody/tr[2]/td[12]').snapshotItem(0);
					totalTroopsIconsRow.appendChild(currentTroopsHeroIconCell.cloneNode(true));
					// create the hero amount cell (with 0 amount, it will be added as normal)
					var totalTroopsRow = xpathEvaluateInContext(totalTable, 'tbody/tr[3]').snapshotItem(0);
					var newHeroAmountCell = currentTroopsCells.cells[11].cloneNode(true);
					newHeroAmountCell.innerHTML = 0;
					totalTroopsRow.appendChild(newHeroAmountCell);
				}

				debug("[transformPageRallyPoint_addOwnTownTotalTroopsTable] adding troops");
				// ADDS UP THE TROOPS
				for(var j=1; j<currentTroopsCells.cells.length; j++) {	// cell 0 has the word "troops"
					totalTroopsCells.cells[j].innerHTML = parseInt(totalTroopsCells.cells[j].innerHTML) + parseInt(currentTroopsCells.cells[j].innerHTML);
				}
			}
			debug("[transformPageRallyPoint_addOwnTownTotalTroopsTable] greying totals");
			// make the totals 0s greyed out and the non-0s non-grayed out
			for(var j=1; j<totalTroopsCells.cells.length; j++) {	// cell 0 has the word "troops"
				totalTroopsCells.cells[j].className = (totalTroopsCells.cells[j].innerHTML == 0) ? "c" : "";
			}
			// remove the upkeep/arrival time row
			var upkeepRow = xpathEvaluateInContext(totalTable, 'tbody/tr[4]').snapshotItem(0);
			upkeepRow.innerHTML = "";
			// change the title row
			var titleRow = xpathEvaluateInContext(totalTable, 'tbody/tr[1]').snapshotItem(0);
			var titleRowCells = xpathEvaluateInContext(totalTable, 'tbody/tr[1]/td').snapshotItem(0);
			titleRow.innerHTML = "";
			titleRow.appendChild(titleRowCells);
			titleRowCells.colSpan = 0;
			// add the created table with the totals
			var paragraph = xpathEvaluate('//div[@id="lmid2"]/p[@class="f10"]').snapshotItem(0);
			paragraph.parentNode.insertBefore(totalTable, paragraph.nextSibling);
		}
	}
	
	function getActiveVillageCoordZ() {
		var activeVillageLink = xpathEvaluate('//a[@class="active_vl"]/../../td/table/tbody/tr/td');
		var coordXCurrentActiveVillage = -10000;
		var coordYCurrentActiveVillage = -10000;
		if (activeVillageLink.snapshotLength > 0) {
			coordXCurrentActiveVillage = parseInt(activeVillageLink.snapshotItem(0).innerHTML.replace("(", ""));
			coordYCurrentActiveVillage = parseInt(activeVillageLink.snapshotItem(2).innerHTML.replace(")", ""));
		}
		return coordsXYToZ(coordXCurrentActiveVillage, coordYCurrentActiveVillage);
	}

	/**
	* savePermanentLang_Reinforcements
	*/
	function savePermanentLang_Reinforcements(txt) {
		GM_EscapeAndSave(createPermanentKeyForLangReinforcements(), txt);
	}	
	
	/**
	* createPermanentKeyForLangReinforcements
	* Creates a key for permanent storing the word for reinforcements as used in the Rally Point.
	* The key is of this format: <server>_<userId>_lang_reinforcements
	*/
	function createPermanentKeyForLangReinforcements() {
		return DEF_PARTIALPERMANENTMKEY_PREFIX + DEF_PARTIALPERMANENTMKEY_LANG_REINFORCEMENTS;
	}
	
	/**
	* xpathEvaluate Finds nodes in the HTML DOM using XPath expression.
	* @param {String} xpathExpr XPath expression to be evaluated and found in the document.
	* @return Node iterator with the nodes that obey the XPath expression. 
	*/
	function xpathEvaluate(xpathExpr) {
			return document.evaluate(xpathExpr, document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null );
	}

	/**
	* xpathEvaluate Finds nodes in the HTML DOM using XPath expression.
	* @param {Node} context Node from where to search.
	* @param {String} xpathExpr XPath expression to be evaluated and found in the document.
	* @return Node iterator with the nodes that obey the XPath expression. 
	*/
	function xpathEvaluateInContext(context, xpathExpr) {
		return document.evaluate(xpathExpr, context, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null );
	}
	
	/**
	* getParamFromUrl
	* @param {String} url The string of the URL
	* @param {String} urlParam The param being searched in the URL
	*/
	function getParamFromUrl(url, urlParam) {
		var res = "&" + url.substring(url.indexOf("?") + 1); //exclude "?" and before that
		var searchStr = "&" + urlParam + "=";
		var pos = res.indexOf(searchStr);
		if (pos != -1) {
			res = res.substring(res.indexOf(searchStr) + searchStr.length);
			var endPos = (res.indexOf("&") > res.indexOf("#")) ? res.indexOf("&") : res.indexOf("#");
			if (endPos != -1) {
			 	res = res.substring(0, endPos);
			}
			return res;
		} else {
			return;
		}
	}
	
	/**
	* coordsXYToZ
	*
	* @param {int} x The X coordinate of a map location.
	* @param {int} y The Y coordinate of a map location.
	* @return The absolute coordinate of a town / abandoned valley / oasis.
	*/
	function coordsXYToZ(x, y) {
		var coordZ = (x + 401) + ((400 - y) * 801);
		return coordZ;
	}	
	
	// Gets current server
	function getServerName() {
	//	return location.href.match(/([\w]+[.]travian.[\w]+([.][\w]+)?)/i)[1];
		return location.href.match(/([\w]+[.]travian([\d]?).[\w]+([.][\w]+)?)/i)[1];
	}

	// Gets current full server name
	function getFullServerName() {
		return location.href.match(/([\w]+:\/\/[\w]+[.]travian([\d]?).[\w]+([.][\w]+)?)/i)[1];
	}

	// Gets the current player	
	function getUserId() {
		var userID = xpathEvaluate('//a[contains(@href, "spieler.php?uid=")]');
		return getParamFromUrl(userID.snapshotItem(0).href, "uid");
	}


	function getCoordZfromHref(url) {
		var coordZ = getParamFromUrl(url, 'd');
		coordZ = (coordZ) ? coordZ : getParamFromUrl(url, 'z');
		return coordZ;
	}	
	
	/**
	* GM_EscapeAndSave
	* @param {string} key 
	* @param {string} value 
	*/
	function GM_EscapeAndSave(key, value) {
		debug("[GM_EscapeAndSave] key " + key + " txt " + value);
		GM_setValue(key, escape(value));
	}

	function debug(txt) {
	 	//GM_log(txt);
	}

	main();

},false);